home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / restore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  22.3 KB  |  950 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)restore.c    3.1    93/04/06    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "lev.h"
  7. #include "termcap.h" /* for TERMLIB and ASCIIGRAPH */
  8.  
  9. #ifdef MICRO
  10. extern int dotcnt;    /* shared with save */
  11. #endif
  12.  
  13. #ifdef ZEROCOMP
  14. static int NDECL(mgetc);
  15. #endif
  16. static void NDECL(find_lev_obj);
  17. #ifndef NO_SIGNAL
  18. static void NDECL(inven_inuse);
  19. #endif
  20. static void FDECL(restlevchn, (int));
  21. static void FDECL(restdamage, (int,BOOLEAN_P));
  22. static struct obj * FDECL(restobjchn, (int,BOOLEAN_P));
  23. static struct monst * FDECL(restmonchn, (int,BOOLEAN_P));
  24. static void FDECL(restgenoinfo, (int));
  25. static boolean FDECL(restgamestate, (int, unsigned int *));
  26. static int FDECL(restlevelfile, (int,XCHAR_P));
  27.  
  28. #ifdef AMII_GRAPHICS
  29. void NDECL( amii_setpens );        /* use colors from save file */
  30. #endif
  31.  
  32. #ifdef MULDGN
  33. #include "quest.h"
  34. #endif
  35.  
  36. boolean restoring = FALSE;
  37. #ifdef TUTTI_FRUTTI
  38. static NEARDATA struct fruit *oldfruit;
  39. #endif
  40. static NEARDATA long omoves;
  41.  
  42. /* Recalculate level.objects[x][y], since this info was not saved. */
  43. static void
  44. find_lev_obj()
  45. {
  46.     register struct obj *fobjtmp = (struct obj *)0;
  47.     register struct obj *otmp;
  48.     int x,y;
  49.  
  50.     for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
  51.         level.objects[x][y] = (struct obj *)0;
  52.  
  53.     /* Reverse the entire fobj chain, which is necessary so that we can
  54.      * place the objects in the proper order.
  55.      */
  56.     while ((otmp = fobj) != 0) {
  57.         fobj = otmp->nobj;
  58.         otmp->nobj = fobjtmp;
  59.         fobjtmp = otmp;
  60.     }
  61.     /* Set level.objects (as well as reversing the chain back again) */
  62.     while ((otmp = fobjtmp) != 0) {
  63.         place_object(otmp, otmp->ox, otmp->oy);
  64.         fobjtmp = otmp->nobj;
  65.         otmp->nobj = fobj;
  66.         fobj = otmp;
  67.     }
  68. }
  69.  
  70. #ifndef NO_SIGNAL
  71. static void
  72. inven_inuse()
  73. /* Things that were marked "in_use" when the game was saved (ex. via the
  74.  * infamous "HUP" cheat) get used up here.
  75.  */
  76. {
  77.     register struct obj *otmp, *otmp2;
  78.  
  79.     for(otmp = invent; otmp; otmp = otmp2) {
  80.         otmp2 = otmp->nobj;
  81.         if(otmp->in_use) {
  82.             /* in_use and oldcorpse share a bit, but we don't
  83.              * want nasty messages for old corpses --
  84.              * remove_cadavers() will clean them up nicely
  85.              */
  86.             if (otmp->otyp == CORPSE &&
  87.                     mons[otmp->corpsenm].mlet == S_TROLL)
  88.                 continue;
  89.             pline("Finishing off %s...", xname(otmp));
  90.             useup(otmp);
  91.         }
  92.     }
  93. }
  94. #endif
  95.  
  96. static void
  97. restlevchn(fd)
  98. register int fd;
  99. {
  100.     int cnt;
  101.     s_level    *tmplev, *x;
  102.  
  103.     sp_levchn = (s_level *) 0;
  104.     mread(fd, (genericptr_t) &cnt, sizeof(int));
  105.     for(; cnt > 0; cnt--) {
  106.  
  107.         tmplev = (s_level *)alloc(sizeof(s_level));
  108.         mread(fd, (genericptr_t) tmplev, sizeof(s_level));
  109.         if(!sp_levchn) sp_levchn = tmplev;
  110.         else {
  111.  
  112.         for(x = sp_levchn; x->next; x = x->next);
  113.         x->next = tmplev;
  114.         }
  115.         tmplev->next = (s_level *)0;
  116.     }
  117. }
  118.  
  119. static void
  120. restdamage(fd, ghostly)
  121. int fd;
  122. boolean ghostly;
  123. {
  124.     int counter;
  125.     struct damage *tmp_dam;
  126.  
  127.     mread(fd, (genericptr_t) &counter, sizeof(counter));
  128.     if (!counter)
  129.         return;
  130.     tmp_dam = (struct damage *)alloc(sizeof(struct damage));
  131.     while (1) {
  132.         char damaged_shops[5], *shp = NULL;
  133.  
  134.         mread(fd, (genericptr_t) tmp_dam, sizeof(*tmp_dam));
  135.         if (ghostly)
  136.         tmp_dam->when += (monstermoves - omoves);
  137.         Strcpy(damaged_shops,
  138.            in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
  139.         if (u.uz.dlevel) {
  140.         /* when restoring, there are two passes over the current
  141.          * level.  the first time, u.uz isn't set, so neither is
  142.          * shop_keeper().  just wait and process the damage on
  143.          * the second pass.
  144.          */
  145.         for (shp = damaged_shops; *shp; shp++) {
  146.             struct monst *shkp = shop_keeper(*shp);
  147.  
  148.             if (shkp && inhishop(shkp) && repair_damage(shkp, tmp_dam))
  149.             break;
  150.         }
  151.         }
  152.         if (!shp || !*shp) {
  153.         tmp_dam->next = level.damagelist;
  154.         level.damagelist = tmp_dam;
  155.         tmp_dam = (struct damage *)alloc(sizeof(*tmp_dam));
  156.         }
  157.         if (!(--counter)) {
  158.         free((genericptr_t)tmp_dam);
  159.         return;
  160.         }
  161.     }
  162. }
  163.  
  164. static struct obj *
  165. restobjchn(fd, ghostly)
  166. register int fd;
  167. boolean ghostly;
  168. {
  169.     register struct obj *otmp, *otmp2 = 0;
  170.     register struct obj *first = (struct obj *)0;
  171. #ifdef TUTTI_FRUTTI
  172.     register struct fruit *oldf;
  173. #endif
  174.     int xl;
  175.  
  176.     while(1) {
  177.         mread(fd, (genericptr_t) &xl, sizeof(xl));
  178.         if(xl == -1) break;
  179.         otmp = newobj(xl);
  180.         if(!first) first = otmp;
  181.         else otmp2->nobj = otmp;
  182.         mread(fd, (genericptr_t) otmp,
  183.                     (unsigned) xl + sizeof(struct obj));
  184.         if(!otmp->o_id) otmp->o_id = flags.ident++;
  185. #ifdef TUTTI_FRUTTI
  186.         if(ghostly && otmp->otyp == SLIME_MOLD) {
  187.             for(oldf=oldfruit; oldf; oldf=oldf->nextf)
  188.                 if (oldf->fid == otmp->spe) break;
  189.             if(!oldf) impossible("no old fruit?");
  190.             else otmp->spe = fruitadd(oldf->fname);
  191.         }
  192. #endif
  193.         /* Ghost levels get object age shifted from old player's clock
  194.          * to new player's clock.  Assumption: new player arrived
  195.          * immediately after old player died.
  196.          */
  197.         if (ghostly && otmp->otyp != OIL_LAMP
  198.                 && otmp->otyp != BRASS_LANTERN
  199.                 && otmp->otyp != CANDELABRUM_OF_INVOCATION
  200.                 && !Is_candle(otmp))
  201.             otmp->age = monstermoves-omoves+otmp->age;
  202.  
  203.         /* get contents of a container or statue */
  204.         if (Has_contents(otmp))
  205.             otmp->cobj = restobjchn(fd,ghostly);
  206.  
  207.         otmp2 = otmp;
  208.     }
  209.     if(first && otmp2->nobj){
  210.         impossible("Restobjchn: error reading objchn.");
  211.         otmp2->nobj = 0;
  212.     }
  213.  
  214.     return(first);
  215. }
  216.  
  217. static struct monst *
  218. restmonchn(fd, ghostly)
  219. register int fd;
  220. boolean ghostly;
  221. {
  222.     register struct monst *mtmp, *mtmp2 = 0;
  223.     register struct monst *first = (struct monst *)0;
  224.     int xl;
  225.     struct permonst *monbegin;
  226.     boolean moved;
  227.  
  228.     /* get the original base address */
  229.     mread(fd, (genericptr_t)&monbegin, sizeof(monbegin));
  230.     moved = (monbegin != mons);
  231.  
  232.     while(1) {
  233.         mread(fd, (genericptr_t) &xl, sizeof(xl));
  234.         if(xl == -1) break;
  235.         mtmp = newmonst(xl);
  236.         if(!first) first = mtmp;
  237.         else mtmp2->nmon = mtmp;
  238.         mread(fd, (genericptr_t) mtmp, (unsigned) xl + sizeof(struct monst));
  239.         if(!mtmp->m_id)
  240.             mtmp->m_id = flags.ident++;
  241.         if (moved && mtmp->data) {
  242.             int offset = mtmp->data - monbegin;    /*(ptrdiff_t)*/
  243.             mtmp->data = mons + offset;  /* new permonst location */
  244.         }
  245.         if(mtmp->minvent)
  246.             mtmp->minvent = restobjchn(fd, ghostly);
  247. #ifdef MUSE
  248.         if (mtmp->mw) {
  249.             struct obj *obj;
  250.  
  251.             for(obj = mtmp->minvent; obj; obj = obj->nobj)
  252.                 if (obj->owornmask & W_WEP) break;
  253.             if (obj) mtmp->mw = obj;
  254.             else {
  255.                 MON_NOWEP(mtmp);
  256.                 impossible("bad monster weapon restore");
  257.             }
  258.         }
  259. #endif
  260.         if (mtmp->isshk) restshk(mtmp, ghostly);
  261.         if (mtmp->ispriest) restpriest(mtmp, ghostly);
  262.  
  263.         mtmp2 = mtmp;
  264.     }
  265.     if(first && mtmp2->nmon){
  266.         impossible("Restmonchn: error reading monchn.");
  267.         mtmp2->nmon = 0;
  268.     }
  269.     return(first);
  270. }
  271.  
  272. static void
  273. restgenoinfo(fd)
  274. register int fd;
  275. {
  276.     register int i;
  277.     unsigned genolist[NUMMONS];
  278.  
  279.     mread(fd, (genericptr_t) genolist, sizeof(genolist));
  280.  
  281.     for (i = 0; i < NUMMONS; i++)
  282.         mons[i].geno = genolist[i];
  283. }
  284.  
  285. static
  286. boolean
  287. restgamestate(fd, mid)
  288. register int fd;
  289. unsigned int *mid;
  290. {
  291.     struct obj *otmp;
  292.     int tmp;        /* not a register ! */
  293.     struct flag oldflags;
  294. #ifdef TUTTI_FRUTTI
  295.     struct fruit *fruit;
  296. #endif
  297.  
  298.     invent = restobjchn(fd, FALSE);
  299.     migrating_objs = restobjchn(fd, FALSE);
  300.     migrating_mons = restmonchn(fd, FALSE);
  301.     restgenoinfo(fd);
  302.  
  303.     mread(fd, (genericptr_t) &tmp, sizeof tmp);
  304. #ifdef WIZARD
  305.     if(!wizard)
  306. #endif
  307.         if(tmp != getuid()) {        /* strange ... */
  308.         pline("Saved game was not yours.");
  309.         return(FALSE);
  310.         }
  311.  
  312.     oldflags = flags;
  313.     mread(fd, (genericptr_t) &flags, sizeof(struct flag));
  314.     /* Some config file and command line OPTIONS take precedence over
  315.      * those in save file.
  316.      */
  317. #ifdef TERMLIB
  318.     flags.DECgraphics = oldflags.DECgraphics;
  319. #endif
  320. #ifdef ASCIIGRAPH
  321.     flags.IBMgraphics = oldflags.IBMgraphics;
  322. #endif
  323. #ifdef MICRO
  324.     flags.rawio = oldflags.rawio;
  325.     flags.BIOS = oldflags.BIOS;
  326. #endif
  327. #ifdef TEXTCOLOR
  328.     flags.use_color = oldflags.use_color;
  329.     flags.hilite_pet = oldflags.hilite_pet;
  330. #endif
  331. #ifdef MAC_GRAPHICS_ENV
  332.     flags.MACgraphics = oldflags.MACgraphics;
  333.     flags.large_font = oldflags.large_font;
  334. #endif
  335.     /* these come from the current environment; ignore saved values */
  336.     flags.window_inited = oldflags.window_inited;
  337.     flags.msg_history = oldflags.msg_history;
  338.     flags.echo = oldflags.echo;
  339.     flags.cbreak = oldflags.cbreak;
  340. #ifdef NEWS
  341.     flags.news = oldflags.news;
  342. #endif
  343. #ifdef AMII_GRAPHICS
  344.     amii_setpens();        /* use colors from save file */
  345. #endif
  346.     mread(fd, (genericptr_t) &u, sizeof(struct you));
  347.     if(u.uhp <= 0) {
  348.         You("were not healthy enough to survive restoration.");
  349.         /* wiz1_level.dlevel is used by mklev.c to see if lots of stuff is
  350.          * uninitialized, so we only have to set it and not the other stuff.
  351.          */
  352.         wiz1_level.dlevel = 0;
  353.         u.uz.dnum = 0;
  354.         u.uz.dlevel = 1;
  355.         return(FALSE);
  356.     }
  357.  
  358.     /* don't do this earlier to avoid complicating abort above */
  359.     for(otmp = invent; otmp; otmp = otmp->nobj)
  360.         if(otmp->owornmask)
  361.             setworn(otmp, otmp->owornmask);
  362.  
  363.     restore_dungeon(fd);
  364.     mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos);
  365.     restlevchn(fd);
  366.     mread(fd, (genericptr_t) &moves, sizeof moves);
  367.     mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves);
  368. #ifdef MULDGN
  369.     mread(fd, (genericptr_t) &quest_status, sizeof(struct q_score));
  370. #endif
  371.     mread(fd, (genericptr_t) spl_book,
  372.                 sizeof(struct spell) * (MAXSPELL + 1));
  373.     restore_artifacts(fd);
  374.     restore_oracles(fd);
  375.     if(u.ustuck)
  376.         mread(fd, (genericptr_t) mid, sizeof (*mid));
  377.     mread(fd, (genericptr_t) pl_character, sizeof pl_character);
  378.  
  379. #ifdef TUTTI_FRUTTI
  380.     mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
  381.     mread(fd, (genericptr_t) ¤t_fruit, sizeof current_fruit);
  382.     ffruit = 0;
  383.     while (fruit = newfruit(),
  384.            mread(fd, (genericptr_t)fruit, sizeof(struct fruit)),
  385.            fruit->fid) {
  386.         fruit->nextf = ffruit;
  387.         ffruit = fruit;
  388.     }
  389.     dealloc_fruit(fruit);
  390. #endif
  391.     restnames(fd);
  392.     restore_waterlevel(fd);
  393.     return(TRUE);
  394. }
  395.  
  396. /*ARGSUSED*/    /* fd used in MFLOPPY only */
  397. static int
  398. restlevelfile(fd, ltmp)
  399. register int fd;
  400. xchar ltmp;
  401. #ifdef applec
  402. # pragma unused(fd)
  403. #endif
  404. {
  405.     register int nfd;
  406.  
  407.     nfd = create_levelfile(ltmp);
  408.  
  409.     if (nfd < 0)    panic("Cannot open temp level %d!", ltmp);
  410. #ifdef MFLOPPY
  411.     if (!savelev(nfd, ltmp, COUNT_SAVE)) {
  412.  
  413.         /* The savelev can't proceed because the size required
  414.          * is greater than the available disk space.
  415.          */
  416.         pline("Not enough space on `%s' to restore your game.",
  417.             levels);
  418.  
  419.         /* Remove levels and bones that may have been created.
  420.          */
  421.         (void) close(nfd);
  422.         eraseall(levels, alllevels);
  423. # ifndef AMIGA
  424.         eraseall(levels, allbones);
  425.  
  426.         /* Perhaps the person would like to play without a
  427.          * RAMdisk.
  428.          */
  429.         if (ramdisk) {
  430.             /* PlaywoRAMdisk may not return, but if it does
  431.              * it is certain that ramdisk will be 0.
  432.              */
  433.             playwoRAMdisk();
  434.             /* Rewind save file and try again */
  435.             (void) lseek(fd, (off_t)0, 0);
  436.             return dorecover(fd);    /* 0 or 1 */
  437.         } else {
  438. # endif
  439.             pline("Be seeing you...");
  440.             terminate(0);
  441. # ifndef AMIGA
  442.         }
  443. # endif
  444.     }
  445. #endif
  446.     bufon(nfd);
  447.     savelev(nfd, ltmp, WRITE_SAVE | FREE_SAVE);
  448.     bclose(nfd);
  449.     return(2);
  450. }
  451.  
  452. int
  453. dorecover(fd)
  454. register int fd;
  455. {
  456.     unsigned int mid;        /* not a register */
  457.     xchar ltmp;
  458.     int rtmp;
  459.     struct obj *otmp;
  460.  
  461.     minit();    /* ZEROCOMP */
  462.     restoring = TRUE;
  463.     getlev(fd, 0, (xchar)0, FALSE);
  464.     if (!restgamestate(fd, &mid)) {
  465.         (void) close(fd);
  466.         (void) delete_savefile();
  467.         restoring = FALSE;
  468.         return(0);
  469.     }
  470. #ifdef MULDGN
  471.     quest_init();
  472. #endif
  473. #ifdef INSURANCE
  474.     savestateinlock();
  475. #endif
  476.     rtmp = restlevelfile(fd, ledger_no(&u.uz));
  477.     if (rtmp < 2) return(rtmp);  /* dorecover called recursively */
  478.  
  479. #ifdef MICRO
  480. # ifdef AMII_GRAPHICS
  481.     {
  482.     extern struct window_procs amii_procs;
  483.     if(windowprocs.win_init_nhwindows== amii_procs.win_init_nhwindows){
  484.         extern winid WIN_BASE;
  485.         clear_nhwindow(WIN_BASE);    /* hack until there's a hook for this */
  486.     }
  487.     }
  488. # else
  489.     clear_nhwindow(WIN_MAP);
  490. # endif
  491.     clear_nhwindow(WIN_MESSAGE);
  492.     You("return to level %d in %s%s.",
  493.         depth(&u.uz), dungeons[u.uz.dnum].dname,
  494.         flags.debug ? " while in debug mode" :
  495.         flags.explore ? " while in explore mode" : "");
  496.     curs(WIN_MAP, 1, 1);
  497.     dotcnt = 0;
  498.     putstr(WIN_MAP, 0, "Restoring:");
  499. #endif
  500.     while(1) {
  501. #ifdef ZEROCOMP
  502.         if(mread(fd, (genericptr_t) <mp, sizeof ltmp) < 0)
  503. #else
  504.         if(read(fd, (genericptr_t) <mp, sizeof ltmp) != sizeof ltmp)
  505. #endif
  506.             break;
  507.         getlev(fd, 0, ltmp, FALSE);
  508. #ifdef MICRO
  509.         curs(WIN_MAP, 1+dotcnt++, 2);
  510.         putstr(WIN_MAP, 0, ".");
  511.         mark_synch();
  512. #endif
  513.         rtmp = restlevelfile(fd, ltmp);
  514.         if (rtmp < 2) return(rtmp);  /* dorecover called recursively */
  515.     }
  516.  
  517. #ifdef BSD
  518.     (void) lseek(fd, 0L, 0);
  519. #else
  520.     (void) lseek(fd, (off_t)0, 0);
  521. #endif
  522.     minit();    /* ZEROCOMP */
  523.     getlev(fd, 0, (xchar)0, FALSE);
  524.     (void) close(fd);
  525.  
  526. #if defined(WIZARD) || defined(EXPLORE_MODE)
  527.     if(
  528. # ifdef WIZARD
  529.        !wizard
  530. #  ifdef EXPLORE_MODE
  531.            &&
  532. #  endif
  533. # endif
  534. # ifdef EXPLORE_MODE
  535.               !discover
  536. # endif
  537.                 )
  538. #endif
  539.         (void) delete_savefile();
  540. #ifdef REINCARNATION
  541.     if (Is_rogue_level(&u.uz)) assign_rogue_graphics(TRUE);
  542. #endif
  543.     if(u.ustuck) {
  544.         register struct monst *mtmp;
  545.  
  546.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  547.             if(mtmp->m_id == mid) goto monfnd;
  548.         panic("Cannot find the monster ustuck.");
  549.     monfnd:
  550.         u.ustuck = mtmp;
  551.     }
  552. #ifdef MFLOPPY
  553.     gameDiskPrompt();
  554. #endif
  555.     max_rank_sz(); /* to recompute mrank_sz (botl.c) */
  556. #ifdef POLYSELF
  557.     set_uasmon();
  558. #endif
  559.     /* take care of iron ball & chain */
  560.     for(otmp = fobj; otmp; otmp = otmp->nobj)
  561.         if(otmp->owornmask)
  562.             setworn(otmp, otmp->owornmask);
  563. #ifndef NO_SIGNAL
  564.     /* in_use processing must be after:
  565.      *    + The inventory has been read so that freeinv() works.
  566.      *    + The current level has been restored so billing information
  567.      *    is available.
  568.      */
  569.     inven_inuse();
  570. #endif
  571. #ifdef MULDGN
  572.     load_qtlist();    /* re-load the quest text info */
  573. #endif
  574.     reset_attribute_clock();
  575.     /* Set up the vision internals, after levl[] data is loaded */
  576.     /* but before docrt().                        */
  577.     vision_reset();
  578.     vision_full_recalc = 1;    /* recompute vision (not saved) */
  579.     docrt();
  580.     restoring = FALSE;
  581.     clear_nhwindow(WIN_MESSAGE);
  582.     return(1);
  583. }
  584.  
  585. void
  586. trickery()
  587. {
  588.     pline("Strange, this map is not as I remember it.");
  589.     pline("Somebody is trying some trickery here...");
  590.     pline("This game is void.");
  591.     done(TRICKED);
  592. }
  593.  
  594. void
  595. getlev(fd, pid, lev, ghostly)
  596. int fd, pid;
  597. xchar lev;
  598. boolean ghostly;
  599. {
  600.     register struct trap *trap;
  601.     register struct monst *mtmp;
  602.     branch *br;
  603.     int hpid;
  604.     xchar dlvl;
  605.     int x, y;
  606. #ifdef TOS
  607.     short tlev;
  608. #endif
  609.  
  610. #if defined(MSDOS) || defined(OS2)
  611.     setmode(fd, O_BINARY);
  612. #endif
  613. #ifdef TUTTI_FRUTTI
  614.     /* Load the old fruit info.  We have to do it first, so the
  615.      * information is available when restoring the objects.
  616.      */
  617.     if (ghostly) {
  618.         struct fruit *fruit;
  619.  
  620.         oldfruit = 0;
  621.         while (fruit = newfruit(),
  622.                mread(fd, (genericptr_t)fruit, sizeof(struct fruit)),
  623.                fruit->fid) {
  624.             fruit->nextf = oldfruit;
  625.             oldfruit = fruit;
  626.         }
  627.         dealloc_fruit(fruit);
  628.     }
  629. #endif
  630.  
  631.     /* First some sanity checks */
  632.     mread(fd, (genericptr_t) &hpid, sizeof(hpid));
  633. /* CHECK:  This may prevent restoration */
  634. #ifdef TOS
  635.     mread(fd, (genericptr_t) &tlev, sizeof(tlev));
  636.     dlvl=tlev&0x00ff;
  637. #else
  638.     mread(fd, (genericptr_t) &dlvl, sizeof(dlvl));
  639. #endif
  640.     if((pid && pid != hpid) || (lev && dlvl != lev)) {
  641. #ifdef WIZARD
  642.         if (wizard) {
  643.             if (pid && pid != hpid)
  644.                 pline("PID (%d) doesn't match saved PID (%d)!", hpid, pid);
  645.             else if (lev && dlvl != lev)
  646.                 pline("This is level %d, not %d!", dlvl, lev);
  647.         }
  648. #endif
  649.         trickery();
  650.     }
  651.  
  652. #ifdef RLECOMP
  653.     {
  654.         short    i, j;
  655.         uchar    len;
  656.         struct rm r;
  657.         
  658. #if defined(MAC)
  659.         memset ( & r , 0 , sizeof ( r ) ) ; /* Suppress warning about used before set */
  660. #endif
  661.         i = 0; j = 0; len = 0;
  662.         while(i < ROWNO) {
  663.             while(j < COLNO) {
  664.             if(len > 0) {
  665.                 levl[j][i] = r;
  666.                 len -= 1;
  667.                 j += 1;
  668.             } else {
  669.                 mread(fd, (genericptr_t)&len, sizeof(uchar));
  670.                 mread(fd, (genericptr_t)&r, sizeof(struct rm));
  671.             }
  672.             }
  673.             j = 0;
  674.             i += 1;
  675.         }
  676.     }
  677. #else
  678.     mread(fd, (genericptr_t) levl, sizeof(levl));
  679. #endif    /* RLECOMP */
  680.  
  681.     mread(fd, (genericptr_t)&omoves, sizeof(omoves));
  682.     mread(fd, (genericptr_t)&upstair, sizeof(stairway));
  683.     mread(fd, (genericptr_t)&dnstair, sizeof(stairway));
  684.     mread(fd, (genericptr_t)&upladder, sizeof(stairway));
  685.     mread(fd, (genericptr_t)&dnladder, sizeof(stairway));
  686.     mread(fd, (genericptr_t)&sstairs, sizeof(stairway));
  687.     mread(fd, (genericptr_t)&updest, sizeof(dest_area));
  688.     mread(fd, (genericptr_t)&dndest, sizeof(dest_area));
  689.     mread(fd, (genericptr_t)&level.flags, sizeof(level.flags));
  690.  
  691.     fmon = restmonchn(fd, ghostly);
  692.  
  693.     /* regenerate animals while on another level */
  694.     { long tmoves = (monstermoves > omoves) ? monstermoves-omoves : 0;
  695.       register struct monst *mtmp2;
  696.  
  697.       for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  698.         mtmp2 = mtmp->nmon;
  699.         if(mtmp->data->geno & G_GENOD) {
  700.             /* mondead() would try to link the monster's objects
  701.              * into fobj and the appropriate nexthere chain.
  702.              * unfortunately, such things will not have sane
  703.              * values until after find_lev_obj() well below
  704.              * here, so we'd go chasing random pointers if we
  705.              * tried that.  we could save the monster's objects
  706.              * in another chain and insert them in the level
  707.              * later, but that's a lot of work for very little
  708.              * gain.  hence, just throw the objects away via
  709.              * mongone() and pretend the monster wandered off
  710.              * somewhere private before the genocide.
  711.              */
  712.             mongone(mtmp);
  713.             continue;
  714.         }
  715.  
  716.         if (ghostly) {
  717.             /* reset peaceful/malign relative to new character */
  718.             if(!mtmp->isshk)
  719.                 /* shopkeepers will reset based on name */
  720.                 mtmp->mpeaceful = peace_minded(mtmp->data);
  721.             set_malign(mtmp);
  722.         } else if (mtmp->mtame && tmoves > 250)
  723.             mtmp->mtame = mtmp->mpeaceful = 0;
  724.  
  725.         /* restore shape changers - Maarten Jan Huisjes */
  726.         if (mtmp->data == &mons[PM_CHAMELEON]
  727.             && !Protection_from_shape_changers
  728.             && !mtmp->cham)
  729.             mtmp->cham = 1;
  730.         else if(Protection_from_shape_changers) {
  731.             if (mtmp->cham) {
  732.                 mtmp->cham = 0;
  733.                 (void) newcham(mtmp, &mons[PM_CHAMELEON]);
  734.             } else if(is_were(mtmp->data) && !is_human(mtmp->data))
  735.                 new_were(mtmp);
  736.         }
  737.  
  738.         if (!ghostly) {
  739.             long nhp = mtmp->mhp +
  740.                 (regenerates(mtmp->data) ? tmoves : tmoves/20);
  741.  
  742.             if(!mtmp->mcansee && mtmp->mblinded) {
  743.                 if ((long) mtmp->mblinded <= tmoves) {
  744.                     mtmp->mblinded = 0;
  745.                     mtmp->mcansee = 1;
  746.                 } else mtmp->mblinded -= tmoves;
  747.             }
  748.             if(!mtmp->mcanmove && mtmp->mfrozen) {
  749.                 if ((long) mtmp->mfrozen <= tmoves) {
  750.                     mtmp->mfrozen = 0;
  751.                     mtmp->mcanmove = 1;
  752.                 } else mtmp->mfrozen -= tmoves;
  753.             }
  754.             if(mtmp->mflee && mtmp->mfleetim) {
  755.                 if ((long) mtmp->mfleetim <= tmoves) {
  756.                     mtmp->mfleetim = 0;
  757.                     mtmp->mflee = 0;
  758.                 } else mtmp->mfleetim -= tmoves;
  759.             }
  760.             if(nhp >= mtmp->mhpmax)
  761.                 mtmp->mhp = mtmp->mhpmax;
  762.             else
  763.                 mtmp->mhp = nhp;
  764.         }
  765.       }
  766.     }
  767.  
  768.     rest_worm(fd);    /* restore worm information */
  769.     ftrap = 0;
  770.     while (trap = newtrap(),
  771.            mread(fd, (genericptr_t)trap, sizeof(struct trap)),
  772.            trap->tx) {
  773.         trap->ntrap = ftrap;
  774.         ftrap = trap;
  775.     }
  776.     dealloc_trap(trap);
  777.     fobj = restobjchn(fd, ghostly);
  778.     find_lev_obj();
  779.     level.buriedobjlist = restobjchn(fd, ghostly);
  780.     billobjs = restobjchn(fd, ghostly);
  781.     rest_engravings(fd);
  782.     rest_rooms(fd);        /* No joke :-) */
  783.     mread(fd, (genericptr_t)doors, sizeof(doors));
  784.  
  785.     /* reset level.monsters for new level */
  786.     for (x = 0; x < COLNO; x++)
  787.         for (y = 0; y < ROWNO; y++)
  788.         level.monsters[x][y] = (struct monst *) 0;
  789.     for (mtmp = level.monlist; mtmp; mtmp = mtmp->nmon) {
  790.         if (mtmp->isshk)
  791.         set_residency(mtmp, FALSE);
  792.         place_monster(mtmp, mtmp->mx, mtmp->my);
  793.         if (mtmp->wormno) place_wsegs(mtmp);
  794.     }
  795.     restdamage(fd, ghostly);
  796.  
  797.  
  798. #ifdef TUTTI_FRUTTI
  799.     /* Now get rid of all the temp fruits... */
  800.     if (ghostly) {
  801.         struct fruit *fruit;
  802.  
  803.         while(oldfruit) {
  804.             fruit = oldfruit->nextf;
  805.             dealloc_fruit(oldfruit);
  806.             oldfruit = fruit;
  807.         }
  808.     }
  809. #endif
  810.     if (ghostly && lev > ledger_no(&medusa_level) &&
  811.             lev < ledger_no(&stronghold_level) && xdnstair == 0) {
  812.         coord cc;
  813.  
  814.         mazexy(&cc);
  815.         xdnstair = cc.x;
  816.         ydnstair = cc.y;
  817.         levl[cc.x][cc.y].typ = STAIRS;
  818.     }
  819.     if (ghostly && (br = Is_branchlev(&u.uz)) && u.uz.dlevel == 1) {
  820.         d_level ltmp;
  821.  
  822.         if (on_level(&u.uz, &br->end1))
  823.         assign_level(<mp, &br->end2);
  824.         else
  825.         assign_level(<mp, &br->end1);
  826.  
  827.         switch(br->type) {
  828.         case BR_STAIR:
  829.         case BR_NO_END1:
  830.         case BR_NO_END2: /* OK to assign to sstairs if it's not used */
  831.         assign_level(&sstairs.tolev, <mp);
  832.         break;        
  833.         case BR_PORTAL: /* max of 1 portal per level */
  834.         {
  835.             register struct trap *ttmp;
  836.             for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  837.             if (ttmp->ttyp == MAGIC_PORTAL)
  838.                 break;
  839.             if (!ttmp) panic("getlev: need portal but none found");
  840.             assign_level(&ttmp->dst, <mp);
  841.         }
  842.         break;
  843.         }
  844.     } else if (ghostly && !Is_branchlev(&u.uz)) {
  845.         /* Make sure there are no dangling portals.  If so, remove them */
  846.         register struct trap *ttmp;
  847.         for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  848.         if (ttmp->ttyp == MAGIC_PORTAL) {
  849.             deltrap(ttmp);
  850.             break; /* max of 1 portal/level */
  851.         }
  852.     }
  853. }
  854.  
  855. #ifdef ZEROCOMP
  856. #define RLESC '\0'    /* Leading character for run of RLESC's */
  857.  
  858. #ifndef ZEROCOMP_BUFSIZ
  859. #define ZEROCOMP_BUFSIZ BUFSZ
  860. #endif
  861. static NEARDATA unsigned char inbuf[ZEROCOMP_BUFSIZ];
  862. static NEARDATA unsigned short inbufp = 0;
  863. static NEARDATA unsigned short inbufsz = 0;
  864. static NEARDATA short inrunlength = -1;
  865. static NEARDATA int mreadfd;
  866.  
  867. static int
  868. mgetc()
  869. {
  870.     if (inbufp >= inbufsz) {
  871.     inbufsz = read(mreadfd, (genericptr_t)inbuf, sizeof inbuf);
  872.     if (!inbufsz) {
  873.         if (inbufp > sizeof inbuf)
  874.         error("EOF on file #%d.\n", mreadfd);
  875.         inbufp = 1 + sizeof inbuf;  /* exactly one warning :-) */
  876.         return -1;
  877.     }
  878.     inbufp = 0;
  879.     }
  880.     return inbuf[inbufp++];
  881. }
  882.  
  883. void
  884. minit()
  885. {
  886.     inbufsz = 0;
  887.     inbufp = 0;
  888.     inrunlength = -1;
  889. }
  890.  
  891. int
  892. mread(fd, buf, len)
  893. int fd;
  894. genericptr_t buf;
  895. register unsigned len;
  896. {
  897.     /*register int readlen = 0;*/
  898.     mreadfd = fd;
  899.     while (len--) {
  900.     if (inrunlength > 0) {
  901.         inrunlength--;
  902.         *(*((char **)&buf))++ = '\0';
  903.     } else {
  904.         register short ch = mgetc();
  905.         if (ch < 0) return -1; /*readlen;*/
  906.         if ((*(*(char **)&buf)++ = ch) == RLESC) {
  907.         inrunlength = mgetc();
  908.         }
  909.     }
  910.     /*readlen++;*/
  911.     }
  912.     return 0; /*readlen;*/
  913. }
  914.  
  915. #else /* ZEROCOMP */
  916.  
  917. void
  918. minit()
  919. {
  920.     return;
  921. }
  922.  
  923. void
  924. mread(fd, buf, len)
  925. register int fd;
  926. register genericptr_t buf;
  927. register unsigned int len;
  928. {
  929.     register int rlen;
  930.  
  931. #if defined(BSD) || defined(ULTRIX)
  932.     rlen = read(fd, buf, (int) len);
  933.     if(rlen != len){
  934. #else /* e.g. SYSV, __TURBOC__ */
  935.     rlen = read(fd, buf, (unsigned) len);
  936.     if((unsigned)rlen != len){
  937. #endif
  938.         pline("Read %d instead of %u bytes.", rlen, len);
  939.         if(restoring) {
  940.             (void) close(fd);
  941.             (void) delete_savefile();
  942.             error("Error restoring old game.");
  943.         }
  944.         panic("Error reading level file.");
  945.     }
  946. }
  947. #endif /* ZEROCOMP */
  948.  
  949. /*restore.c*/
  950.